/***************************************************************************/
/*                                                                         */
/*  File:   casutils.c                                                     */
/*                                                                         */
/*  Author: B. Rohde                                                       */
/*                                                                         */
/*  Purpose:  Implements utilities for dealing with CAS connection tables. */
/*                                                                         */
//  History:      26-Apr-94       Start of development.                    */
//                                                                         */
/***************************************************************************/

#include "casutils.h"

#include <stdio.h> /* debugging */

#include <string.h>


unsigned char etoa(register unsigned int chr)
/*
 * Converts the EBCDIC character to its ASCII equivalent. It returns
 * ('?' | 0x80) if vharacter is not convertable.
 */
{
    unsigned int tmp;
    static unsigned char asc[] =
    {   /*asc table*/
#if defined (SPARC)
        /*  0       1   2       3   4       5   6       7   */
/* 00 */    0x00, 0x01, 0x02, 0x03, 0x9c, 0x09, 0x86, 0x7f,
/* 08 */    0x97, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
/* 10 */    0x10, 0x11, 0x12, 0x13, 0x9d, 0x0a, 0x08, 0x87,
/* 18 */    0x18, 0x19, 0x92, 0x8f, 0x1c, 0x1d, 0x1e, 0x1f,
/* 20 */    0x80, 0x81, 0x82, 0x83, 0x84, 0x0a, 0x17, 0x1b,
/* 28 */    0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07,
/* 30 */    0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04,
/* 38 */    0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a,
/* 40 */    0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xa4, 0xa5, 0xa6,
/* 48 */    0xe7, 0x00, 0x00, 0x2e, 0x3c, 0x28, 0x2b, 0x7c,
/* 50 */    0x26, 0xe9, 0xea, 0xab, 0xe8, 0xad, 0xee, 0xaf,
/* 58 */    0xb0, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0xac,
/* 60 */    0x2d, 0x2f, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
/* 68 */    0xb8, 0x00, 0xcb, 0x2c, 0x25, 0x5f, 0x3e, 0x3f,
/* 70 */    0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1,
/* 78 */    0xc2, 0x60, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22,
/* 80 */    0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
/* 88 */    0x68, 0x69, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
/* 90 */    0xca, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
/* 98 */    0x71, 0x72, 0x7e, 0x7e, 0xf7, 0xce, 0xcf, 0xd0,
/* a0 */    0xd1, 0x7e, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,/*A1 entry was e5*/
/* a8 */    0x79, 0x7a, 0xd2, 0x00, 0xd4, 0x5b, 0xd6, 0x00,
/* b0 */    0x00, 0x00, 0xda, 0xdb, 0xdc, 0x00, 0x00, 0xdf,
/* b8 */    0x00, 0xe1, 0xe2, 0xe3, 0xe4, 0x5d, 0xe6, 0xe7,
/* c0 */    0x7b, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
/* c8 */    0x48, 0x49, 0xe8, 0xf4, 0xf6, 0xeb, 0xec, 0xed,
/* d0 */    0x7d, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
/* d8 */    0x51, 0x52, 0xa3, 0xfb, 0xfc, 0xf9, 0xf2, 0xf3,
/* e0 */    0x5c, 0x9f, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
/* e8 */    0x59, 0x5a, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
/* f0 */    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
/* f8 */    0x38, 0x39, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
# else
        /*  0       1   2       3   4       5   6       7   */
/* 00 */    0x00, 0x01, 0x02, 0x03, 0x9c, 0x09, 0x86, 0x7f,
/* 08 */    0x97, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
/* 10 */    0x10, 0x11, 0x12, 0x13, 0x9d, 0x0a, 0x08, 0x87,
/* 18 */    0x18, 0x19, 0x92, 0x8f, 0x1c, 0x1d, 0x1e, 0x1f,
/* 20 */    0x80, 0x81, 0x82, 0x83, 0x84, 0x0a, 0x17, 0x1b,
/* 28 */    0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07,
/* 30 */    0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04,
/* 38 */    0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a,
/* 40 */    0x20, 0xa0, 0xa1, 0xd5, 0xd3, 0xa4, 0xa5, 0xa6,
/* 48 */    0xd7, 0x00, 0x00, 0x2e, 0x3c, 0x28, 0x2b, 0x7c,
/* 50 */    0x26, 0xd9, 0xaa, 0xab, 0xd8, 0xad, 0xae, 0xaf,
/* 58 */    0xb0, 0xb9, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x5e,/*5H entry was 7e*/
/* 60 */    0x2d, 0x2f, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
/* 68 */    0xb8, 0x00, 0xcb, 0x2c, 0x25, 0x5f, 0x3e, 0x3f,
/* 70 */    0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1,
/* 78 */    0xc2, 0x60, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22,
/* 80 */    0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
/* 88 */    0x68, 0x69, 0xc4, 0xc3, 0xc6, 0xc7, 0xc8, 0xc9,
/* 90 */    0xca, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
/* 98 */    0x71, 0x72, 0x7e, 0x7e, 0xa8, 0xce, 0xcf, 0xd0,
/* a0 */    0xd1, 0x7e, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,/*A1 entry was e5*/
/* a8 */    0x79, 0x7a, 0xd2, 0x00, 0xd4, 0x5b, 0xd6, 0x00,
/* b0 */    0x00, 0x00, 0xda, 0xdb, 0xdc, 0x00, 0x00, 0xdf,
/* b8 */    0x00, 0xe1, 0xe2, 0xe3, 0xe4, 0x5d, 0xe6, 0xe7,
/* c0 */    0x7b, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
/* c8 */    0x48, 0x49, 0xe8, 0xe9, 0xdd, 0xeb, 0xec, 0xed,
/* d0 */    0x7d, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
/* d8 */    0x51, 0x52, 0xee, 0xef, 0xe0, 0xde, 0xf2, 0xf3,
/* e0 */    0x5c, 0x9f, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
/* e8 */    0x59, 0x5a, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
/* f0 */    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
/* f8 */    0x38, 0x39, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
#endif
   };
   /*If EBCDIC char won't map to ascii return '?' with the 08 bit set*/
   chr &= 0xff;
   tmp = asc[chr];
   return ((unsigned char)tmp);
}      

struct cas_node_entry_t cas_node_table[] =
   {
      {"Ac",  3, "Actinium",    0x20},
      {"Ag",  1, "Silver",      0x22},
      {"Al",  3, "Aluminum",    0x24},
      {"Am",  3, "Americium",   0x26},
      {"Ar",  0, "Argon",       0x28},
      {"As",  3, "Arsenic",     0x2A},
      {"At",  1, "Astatine",    0x2C},
      {"Au",  1, "Gold",        0x2E},
      {"B",   3, "Boron",       0x30},
      {"Ba",  2, "Barium",      0x32},
      {"Be",  2, "Beryllium",   0x34},
      {"Bi",  3, "Bismuth",     0x36},
      {"Bk",  3, "Berkelium",   0x38},
      {"Br",  1, "Bromine",     0x3A},
      {"C",   4, "Carbon",      0x3C},
      {"Ca",  2, "Calcium",     0x3E},
      {"Cd",  2, "Cadmium",     0x40},
      {"Ce",  3, "Cerium",      0x42},
      {"Cf",  3, "Californium", 0x44},
      {"Cl",  1, "Chlorine",    0x46},
      {"Cm",  3, "Curium",      0x48},
      {"Co",  2, "Cobalt",      0x4A},
      {"Cr",  6, "Chromium",    0x4C},
      {"Cs",  1, "Cesium",      0x4E},
      {"Cu",  2, "Copper",      0x50},
      {"D",   1, "Deuterium",   0x52},
      {"D",   1, "Deuterium",   0x52},
      {"Dy",  3, "Dysprosium",  0x54},
      {"Er",  3, "Erbium",      0x56},
      {"Es",  3, "Einsteinium", 0x58},
      {"Eu",  3, "Europium",    0x5A},
      {"F",   1, "Fluorine",    0x5C},
      {"Fe",  2, "Iron",        0x5E},
      {"Fm",  3, "Fermium",     0x60},
      {"Fr",  1, "Francium",    0x62},
      {"Ga",  3, "Gallium",     0x64},
      {"Gd",  3, "Gadolinium",  0x66},
      {"Ge",  4, "Germanium",   0x68},
      {"H",   0, "Hydrogen",    0x6A},
      {"He",  0, "Helium",      0x6C},
      {"Hf",  4, "Hafnium",     0x6E},
      {"Hg",  2, "Mercury",     0x70},
      {"Ho",  3, "Holmium",     0x72},
      {"I",   1, "Iodine",      0x74},
      {"In",  3, "Indium",      0x76},
      {"Ir",  2, "Iridium",     0x78},
      {"K",   1, "Potassium",   0x7A},
      {"Kr",  0, "Krypton",     0x7C},
      {"La",  3, "Lanthanum",   0x7E},
      {"Li",  1, "Lithium",     0x80},
      {"Lu",  3, "Lutetium",    0x82},
      {"Lw",  3, "Lawrencium",  0x84},
      {"Md",  3, "Mendelevium", 0x86},
      {"Mg",  2, "Magnesium",   0x88},
      {"Mn",  7, "Manganese",   0x8A},
      {"Mo",  6, "Molybdenum",  0x8C},
      {"N",   3, "Nitrogen",    0x8E},
      {"Na",  1, "Sodium",      0x90},
      {"Nb",  5, "Niobium",     0x92},
      {"Nd",  3, "Neodymium",   0x94},
      {"Ne",  0, "Neon",        0x96},
      {"Ni",  2, "Nickel",      0x98},
      {"No",  3, "Nobelium",    0x9A},
      {"Np",  5, "Neptumium",   0x9C},
      {"O",   2, "Oxygen",      0x9E},
      {"Os",  2, "Osmium",      0xA0},
      {"P",   3, "Phorphorus",  0xA2},
      {"Pa",  5, "Protactinium",0xA4},
      {"Pb",  4, "Lead",        0xA6},
      {"Pd",  2, "Palladium",   0xA8},
      {"Pm",  3, "Promethium",  0xAA},
      {"Po",  2, "Polonium",    0xAC},
      {"Pr",  3, "Praseodymium",0xAE},
      {"Pt",  2, "Platinum",    0xB0},
      {"Pu",  4, "Plutonium",   0xB2},
      {"Ra",  2, "Radium",      0xB4},
      {"Rb",  1, "Rubidium",    0xB6},
      {"Re",  7, "Rhenium",     0xB8},
      {"Rh",  0, "Rhodium",     0xBA},
      {"Rn",  2, "Radon",       0xBC},
      {"Ru",  2, "Ruthemium",   0xBE},
      {"S",   2, "Sulphur",     0xC0},
      {"Sb",  3, "Antimony",    0xC2},
      {"Sc",  3, "Scandium",    0xC4},
      {"Se",  2, "Selenium",    0xC6},
      {"Si",  4, "Silicon",     0xC8},
      {"Sm",  3, "Samarium",    0xCA},
      {"Sn",  4, "Tin",         0xCC},
      {"Sr",  2, "Strontium",   0xCE},
      {"T",   1, "Tritium",     0xD0},
      {"Ta",  5, "Tantalium",   0xD2},
      {"Tb",  3, "Terbium",     0xD4},
      {"Tc",  7, "Technetium",  0xD6},
      {"Te",  2, "Tellerium",   0xD8},
      {"Th",  4, "Thorium",     0xDA},
      {"Ti",  4, "Titanium",    0xDC},
      {"Tl",  1, "Thallium",    0xDE},
      {"Tm",  3, "Thulium",     0xE0},
      {"U",   6, "Uranium",     0xE2},
      {"V",   5, "Vanadium",    0xE4},
      {"W",   6, "Tungsten",    0xE6},
      {"Xe",  0, "Xenon",       0xE8},
      {"Y",   3, "Yttrium",     0xEA},
      {"Yb",  3, "Ytterbium",   0xEC},
      {"Zn",  2, "Zinc",        0xEE},
      {"Zr",  4, "Zirconium",   0xF0},
      {"??",  0, "Error",       0x00}
   };

struct cas_node_entry_t *ToNodeEntry(unsigned char hex_value)
/*
 * Translates the numeric CAS node hex_value to a pointer to the
 * corresponding entry in cas_node_table. If the node hex_value is not
 * found in the table, a pointer to the last element is returned.
 */
{
   struct cas_node_entry_t *result;

   result = cas_node_table;
   while (result->hex_value != 0)
      if (result->hex_value == hex_value) return (result);
      else                              result++;
   return (result);
}

int CASValence(char *symbol)
/*
 * Returns the preferred valence of the element *symbol in the CAS
 * convention system.
 *
 * The function returns 0 for unknown elements;
 */
{
   struct cas_node_entry_t *result;

   result = cas_node_table;
   while (result->hex_value != 0)
      if (0 == strcmp(result->symbol, symbol))
      {
         return (result->valence);
      }
      else
         result++;
   return (result->valence);
}
